#ifndef __SUR_IMPLS_H__
#define __SUR_IMPLS_H__

#include <list>
#include <errno.h>
#include <sys/statvfs.h>
#include <math.h>

#include "local_cache.hpp"
#include "common.h"
#include "gwlib.h"

using namespace std;
using namespace dicom;

#define MAP_LIMIT 1000
#define FS_BLKSIZE 512

typedef struct sur_file_handler {
	
	FILE* tmp_fh_;
	string tmp_name;
	off_t pos;
	int flag; //__sync_fetch_and_add
	string file_name;
	string gw_id;
	string gw_pid;
	pthread_mutex_t mutex;
} sur_fh;

class sur_impls
{
public:
	sur_impls(const string& server, const string& user, const string& pw,
				const string& ukey_id, const string& cache_path, int cache_size = 0);

	~sur_impls();
public:
	int sur_init();
	int sur_destroy();
	int sur_access(const char *path, int mask);
	int sur_open(const char *path, int flag, sur_fh *fh);
	int sur_create(const char *path, sur_fh *fh);
	size_t sur_read(const char *path, char *buf, size_t size, off_t offset, sur_fh *fh);
	size_t sur_write(const char *path, const char *buf, size_t size, off_t offset, sur_fh *fh);
	int sur_release (const char *path, sur_fh *fh);
	int sur_flush(const char *path, sur_fh *fh);
	
	int sur_statfs(struct statvfs *st);
	int sur_truncate(const char *path, off_t size);
	int sur_unlink(const char *path);
	int sur_getattr(const char *path, struct stat *st);
	int sur_rename(const char *from, const char *to);
	int sur_readdir(const char *path, vector<DirEntry>& ctx);
	int sur_mkdir(const char *path);
	int sur_rmdir(const char *path);
	int sur_utimens(const char *path, const struct timespec ts[2]);
	int sur_chmod(const char *path, mode_t mode);
	
	static int write_hook(const void* buf, size_t n, void* data);
	static int read_hook(void* buf, size_t n, void* data);
	
private:
	inline int deal_path(const string& path, string& dir, string& f_name);
	int parse_pid(const string& path, string& pid);
private:
	local_cache lcache_;
	GwToken* gw_;
	string server_;
	string user_;
	string pw_;
	string ukey_id_;
};


#endif
